
package com.catsic.core.organ.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.catsic.base.BaseServiceImpl;
import com.catsic.base.exception.CatsicException;
import com.catsic.base.tree.TreeInfo;
import com.catsic.core.conditon.OrganCondition;
import com.catsic.core.constants.Constants;
import com.catsic.core.convert.Converts;
import com.catsic.core.entity.Organ;
import com.catsic.core.exception.CatsicExceptionCode;
import com.catsic.core.form.OrganForm;
import com.catsic.core.organ.dao.OrganDao;
import com.catsic.core.organ.service.OrganService;
import com.catsic.core.specification.OrganSpec;

/**
 * ClassName: OrganServiceImpl
 * Description: 机构相关功能
 * date: 2014年2月27日 上午9:11:55
 * author: huyulei
 */
 
@Service("organService")
public class OrganServiceImpl extends BaseServiceImpl<Organ,String> implements OrganService{

	@Autowired
	private OrganDao organDao;
	
	/**
	 * @see com.catsic.core.base.BaseServiceImpl#add(java.lang.Object)
	 */
	@Override
	public OrganForm add(OrganForm form){
		/**
		 * 查询父节点
		 */
		Organ parent = null;
		if(form.getPid() != null){
			parent = findById(form.getPid());
		}
		Organ organ = new Organ();
		organ.setName(form.getName());
		organ.setJb(parent.getJb() + 1);
		organ.setParent(parent);
		organ.setCode(code(form.getPid()));
		organ = super.add(organ);
		return Converts.convert(organ);
	}
	
	/**
	 * 生成机构编码规则
	 * @param pid
	 * @return
	 */
	private String code(String id){
		/**
		 * 查询父节点下的所有子节点
		 */
		List<Organ> childs = organDao.findByCodeIsNotNullAndParentCodeOrderByCodeDesc(id);
		Organ parent = findById(id);
		if(CollectionUtils.isNotEmpty(childs)){
			String code = childs.get(0).getCode();
			int length = code.length();
			return String.format("%0" + length + "d", Long.valueOf(code)+ 1);
		}else {
			return parent == null ? String.format("%0" + Constants.编码位数 + "d",0) : parent.getCode() + String.format("%0" + Constants.编码位数 + "d",0);
		}
	}

	/* 
	 * @see com.catsic.core.organ.service.OrganService#code(java.lang.Integer, java.lang.String)
	 */
	public void code(Integer jb,String code){
		List<Organ> list = organDao.findByCodeIsNull();
		if(CollectionUtils.isEmpty(list)){
			return;
		}
		/**
		 * 查询父节点下的所有子节点
		 */
		List<Organ> childs = organDao.findByJbAndCodeOrderByCodeDesc(jb, code);
		if(CollectionUtils.isNotEmpty(childs)){
			for(Organ organ : childs){
				Organ parent = organ.getParent();
				if(parent != null){
					organ.setCode(code(organ.getParent().getId()));
					organ.setJb(parent.getJb() + 1);
					super.update(organ);
				}
			}
			code(jb + 1,null);
		}
	}
	
	/**
	 * @see com.catsic.core.organ.service.OrganService#update(com.catsic.core.form.OrganForm)
	 */
	@Override
	public OrganForm update(OrganForm form){
		Organ organ = findById(form.getId());
		organ.setName(form.getName());
		organ = super.add(organ);
		return Converts.convert(organ);
	}
	
	/**
	 * @see com.catsic.core.base.BaseServiceImpl#delete(java.io.Serializable)
	 */
	@Override
	public void delete(String id) {
		Organ organ = findById(id);
		organDao.delete(organ);
	}
	
	/**
	 * @see com.catsic.core.organ.service.OrganService#findById(java.lang.Long)
	 */
	public Organ findById(String id){
		Organ organ = getById(id);
		if(null == organ){
			throw new CatsicException(CatsicExceptionCode.实体不存在,Constants.ORGAN);
		}
		return organ;
	}
	
	public Organ findOrgById(String id){
		Organ organ = organDao.findByDescription(id);
		return organ;
	}
	
	public Organ findOrgByPid(String id){
		Organ organ = organDao.findByDescription(id);
		if(null == organ){
			organ=organDao.findByDescription("1");
		}
		return organ;
	}
	
	/**
	 * @see com.catsic.core.organ.service.OrganService#findOrganById(java.lang.Long)
	 */
	public OrganForm findOrganById(String id){
		OrganForm organForm = Converts.convert(findById(id));
		return organForm;
	}
	
	/**
	 * @see com.catsic.core.organ.service.OrganService#findByCode(java.lang.String)
	 */
	public Organ findByCode(String code){
		/**
		 * code 不可为空或null
		 */
		if(StringUtils.isBlank(code)){
			throw new CatsicException(CatsicExceptionCode.编码不能为空,Constants.ORGAN);
		}
		Organ organ = organDao.findByCode(code);
		if(null == organ){
			throw new CatsicException(CatsicExceptionCode.实体不存在,Constants.ORGAN);
		}
		return organ;
	}
	
	/** 
	 * @see com.catsic.core.organ.service.OrganService#findByPid(java.lang.String)
	 */
	public List<Organ> findByPid(String id){
		return organDao.findByPid(id);
	}
	
	/** 
	 * @see com.catsic.core.organ.service.OrganService#findByPcode(java.lang.String)
	 */
	public List<Organ> findByPcode(String code){
		return organDao.findByPcode(code);
	}
	
	/** 
	 * @see com.catsic.core.organ.service.OrganService#tree(java.lang.String)
	 */
	public List<TreeInfo> getTreeInfo(String id){
		List<Organ> list = findByPid(id);
		List<TreeInfo> listForm = new ArrayList<TreeInfo>();
		for(Organ organ : list){
			TreeInfo treeInfo = Converts.convertTree(organ);
			listForm.add(treeInfo);
		}
		return listForm;
	}
	
	/**
	 * @see com.catsic.core.organ.service.OrganService#query(java.lang.String)
	 */
	public List<OrganForm> query(String id){
		List<Organ> list = findByPid(id);
		List<OrganForm> listForm = new ArrayList<OrganForm>();
		for(Organ organ : list){
			OrganForm form = Converts.convert(organ);
			listForm.add(form);
		}
		return listForm;
	}
	
	/**
	 * @see com.catsic.core.organ.service.OrganService#query(java.lang.Object)
	 */
	public List<TreeInfo> query(OrganCondition condition){
		OrganSpec spec = new OrganSpec(condition);
		List<Organ> list = organDao.findAll(spec);
		List<TreeInfo> listForm = new ArrayList<TreeInfo>();
		for(Organ organ : list){
			TreeInfo treeInfo = Converts.convertTree(organ);
			if(!listForm.contains(treeInfo))
				listForm.add(treeInfo);
			Organ parent = organ;
			while(parent != null && !StringUtils.equals(parent.getCode(), condition.getCode())){
				treeInfo = Converts.convertTree(parent);
				if(!listForm.contains(treeInfo))
					listForm.add(treeInfo);
				parent = parent.getParent();
			}
		}
		return listForm;
	}
	
	public Page<OrganForm> findAll(OrganCondition condition, Pageable pageable){
		OrganSpec spec = new OrganSpec(condition);
		Page<Organ> page = organDao.findAll(spec, pageable);
		List<OrganForm> listForm = new ArrayList<OrganForm>();
		for(Organ organ :page.getContent()){
			listForm.add(Converts.convert(organ));
	    }
	    Page<OrganForm> page_ = new PageImpl<OrganForm>(listForm,pageable,page.getTotalElements());
	    return page_;
	}
	
	@Override
	public List<OrganForm> listForm(List<Organ> list){
		List<OrganForm> listForm = new ArrayList<OrganForm>();
		for(Organ organ : list){
			listForm.add(Converts.convert(organ));
		}
		return listForm;
	}
}
